
//package cfu_main.fir;
/*
 * This file creates the array of 8x8 CFU (total 64 CFUs). It verifies the functionality od FIR filter
 * Filter configuration: 
 * 		LCF = ; HCF = ;Sampling frequency =;Taps = 25; Number of channels = 1;
 * 		
 * 
 * 
 */

import javax.swing.JOptionPane;
import java.io.*;
//import java.util.*;



/*This is class file for the Instruction Set Simulator for SIMD approach.
 * This class defines main instructions each CFU can perform*/  

/*The following instructions are used in this architecture. There is a method
 * for each instruction which takes some arguments and returns output; These 
 * will be mostly registyers.
 * 
 * 1- ADD - Addition of two 16 bits data 
 * 2- MAC - Multiply and accumulation (MAC) in single cycle; We have only used 
 * 			MAC unit instead of multiply unit to  
 * 3- SLL - Shift Left Logical
 * 4- SRL - Shift Right Logical
 * 5- NOP - No Operation
 * 6- ADM - Addition and multiplication (ADM) in single cycle, not that the order
 * 			of operation is reverse than MAC instruction. 
 * */



 class Cfu {

	/*Registers; There are four 16 bits registers in each CFU
	 * Two register to hold the input data to process
	 * Two registers to hold the output data because size of the 
	 * output data may be larger than the input data
	 * 
	 * */
	
	 // Global Variables
	 
	public static int[] register_array =  new int[4];
	//public static int = output_register_index;
	//static int out_reg_index;
	//register_array[0]=7;
	public static int instr,
	in_reg1_index,  in_reg2_index,
	in_reg3_index,
	out_reg_index,
	shift_offset;
	
	//Constructor of CFU class. It takes values from the class fir_1 and initialize the CFU
	
/*	public Cfu (int instru,int reg1,int reg2, int reg3, int reg4, int offset)
	{
		
		instr = instru;
		in_reg1_index = reg1;
		in_reg2_index = reg2;
		in_reg3_index = reg3;
		out_reg_index = reg4;
		shift_offset = offset;
		register_array[0]=7;
		register_array[1]=9;
		register_array[2]=11;
	}*/
	public void Cfu_initialize (int instru,int reg1,int reg2, int reg3, int reg4, int offset)
	{
		
		instr = instru;
		in_reg1_index = reg1;
		in_reg2_index = reg2;
		in_reg3_index = reg3;
		out_reg_index = reg4;
		shift_offset = offset;
		register_array[0]=7;
		register_array[1]=9;
		register_array[2]=11;
	}
		
	//Method of Addition operation
	public static void add(int in_reg_index_1,int in_reg_index_2,int out_reg_index)
	{
		
		register_array[out_reg_index] = register_array[in_reg_index_1] + register_array[in_reg_index_2];  
		
	}
	
	//Method of SLL (Shift Left Logical) operation
	public static void sll(int in_reg_index,int shift_offset,int out_reg_index)
	{
		
		register_array[out_reg_index] = register_array[in_reg_index] << shift_offset;  
		
	}
	
	//Method of SRL (Shift Right Logical) operation
	public static void srl(int in_reg_index,int shift_offset,int out_reg_index)
	{
		
		register_array[out_reg_index] = register_array[in_reg_index] >> shift_offset;    
		
	}
	
	//Method of MAC (Multiply Accumulate) operation
	public static void mac(int in_reg_index_1,int in_reg_index_2,int in_reg_index_3,int out_reg_index)
	{
		
		register_array[out_reg_index] = 
			(register_array[in_reg_index_1] * register_array[in_reg_index_2])+register_array[in_reg_index_3];  
		
	}
	
	//Method of ADM (Addition Multiply) operation
	public static void adm(int in_reg_index_1,int in_reg_index_2,int in_reg_index_3,int out_reg_index)
	{
		
		register_array[out_reg_index] = 
			(register_array[in_reg_index_1] + register_array[in_reg_index_2]) * register_array[in_reg_index_3];  
		
	}
	
	
	/*Input arguments to this class will be in the following order
	 * 0- Instruction
	 * 1- 1st input register index 
	 * 2- 2nd input register index; pass null if not required
	 * 3- 3rd input register index; pass null if not required
	 * 4- Output register index
	 * 5- Shift offset	
	*/
	
	
	public int start_CFU()
	{
		
		
		//int instr = Integer.parseInt(args[0]);
		//int in_reg1_index = Integer.parseInt(args[1]);
		//int in_reg2_index = Integer.parseInt(args[2]);
		//int in_reg3_index = Integer.parseInt(args[3]);
		//out_reg_index = Integer.parseInt(args[4]);
		//int shift_offset = Integer.parseInt(args[5]);
		
		/*Instruction Decoding Logic for CFU*/
		
		switch (instr)
		{
		
		// This is NOP operation
		case 0:
			System.out.println("You have chosen NOP instruction and CFU will be idle");
			
			break;
			
		//This is Addition operation
		case 1:
			
			/* Argument order - input register 1 index,
			 * input register 2 index, 
			 * output register index
			 * */
			add(in_reg1_index,in_reg2_index,out_reg_index);
			System.out.println("You have chosen ADD instruction");
			break;

			
		//This is Shift Left logical operation
		case 2:
			sll(in_reg1_index,shift_offset,out_reg_index);
			
			break;
			
		//This is Shift right logical operation
		case 3:
			srl(in_reg1_index,shift_offset,out_reg_index);
			break;
						
		//This is MAC operation	
		case 4:
			mac(in_reg1_index, in_reg2_index, in_reg3_index, out_reg_index);
				
			break;
			
		//This is ADM (Addition and multiplication) operation
		case 5:
			adm(in_reg1_index, in_reg2_index, in_reg3_index, out_reg_index);
			break;
		
		default: JOptionPane.showMessageDialog(null, "The operation to CFU is not valid");
		
	
	
		}
		//JOptionPane.showMessageDialog(null, "The final answer from CFU is "+ register_array[out_reg_index] );
		System.out.println("Your final answer from CFU is "+ register_array[out_reg_index]);
		return (register_array[out_reg_index]);
	}
 }
		
	

//package cfu_main;

/*
 * This will model RAM for the architecture.
 * This class will create a RAM and load data from a text file to RAM.
 * 
 * 
 */


class Ram 
{
	static int ram_size = 2048;
	public static int[] ram = new int [ram_size];
	
	// This is constructor of class Ram. We will fill RAM by reading a text.
	
	public Ram(){
		
		File in_data_file = new File ("test.txt");
		//StringBuffer contents = new StringBuffer();
		String data_line = null;
		
	try 
		{
			BufferedReader in_data_buffer = new BufferedReader(new FileReader(in_data_file));
			
			int data_line_int;
			int ram_array_index=0;
			
			while((data_line = in_data_buffer.readLine()) != null)
			{
				//System.out.println("The input string is " + data_line);
				data_line_int = Integer.parseInt(data_line);
				ram[ram_array_index] = data_line_int;
				ram_array_index ++;
				
			}
			
			for(int i=0;i<ram_array_index;i++)
			{
				//System.out.print("i="+i+"\n" );
				//System.out.print("The input to ram is " + ram[i]+ "\n");
				System.out.print("ram ["+i+"] = " + ram[i]+ "\n");
				
			}
			
			
		}catch (FileNotFoundException e)
			{
				e.printStackTrace();
				System.out.println("The input file for RAM is not found!");
				
			}catch (IOException e)
			{
				e.printStackTrace();
			
		}

	}

}

class fir_1
{
	
	/*Input arguments to this class will be in the following order
	 * 0- Instruction
	 * 1- 1st input register index 
	 * 2- 2nd input register index; pass null if not required
	 * 3- 3rd input register index; pass null if not required
	 * 4- Output register index
	 * 5- Shift offset	
	 */
	public static int no_cfu_row = 8;
	public static int no_cfu_column = 8;
	

	//Cfu[][] Cfu_Array = new Cfu[no_cfu_row][no_cfu_column];
	//Cfu cfu1 = new Cfu(1,0,1,2,3,0);
	
	
	public static void main (String[] args)
	{
/*		Ram ram_fir = new Ram;

		String ram_size_string = JOptionPane.showInputDialog(null,"Enter RAM size:");
		int ram_size_int = Integer.parseInt(ram_size_string);

		ram_fir.Ram(ram_size_int);*/
		//JOptionPane.showMessageDialog(null,"Jai Sairam..The program started...!");
		//Creating array of 8x8 CFUs
		//Cfu[][] Cfu_Array = new Cfu[no_cfu_row][no_cfu_column];
		//Cfu_Array[0][0].Cfu_initialize(1, 0, 1, 2, 3, 0);
		
		Ram fir_ram = new Ram();
		//Cfu cfu1 = new Cfu(4,0,1,2,3,0);
		
		//cfu1.start_CFU();
		//Cfu_Array[0][0].start_CFU();
		
		System.exit(0);	
	}
	
	
	
}
	
